feat(p2p): wire dig-node to its P2P crates (full ladder, DHT locator, address book, dials)#23
Merged
Merged
Conversation
…covery (#385) Every node peer dial (DHT lookups, multi-source range fetches, PEX candidate verification) enabled only [Direct, Relayed] — a NAT'd peer skipped UPnP/NAT-PMP/ PCP + hole-punch and jumped straight to the relay, over-loading relay.dig.net and defeating the "attempt direct traversal before relaying" intent of the IPv6-first rule (§5.2). dig-nat already implements the full ladder; the node just capped it. - Add `net::full_nat_config(timeout, stun_server)` — the ONE shared NatConfig (full ladder from `NatConfig::default`, relay last) used by all call sites. - Wire it at `dht::NatDhtTransport::nat_config`, `download::NodeContent::for_dht`, and `pex::GossipPexPool::offer_candidates` (the 4th site, `find_holders`, is orphaned dead code removed in #386). - Resolve the relay-colocated STUN server once at bring-up (`<relay-host>:3478`) and thread it through so dig-nat's hole-punch tier has a reflexive-address input. - Discover this node's server-reflexive (public) address via STUN and merge it into the advertised candidate set IPv6-first (`net::merge_reflexive`), so a remote peer behind a different NAT can dial/hole-punch to it. IPv6-first preserved: the shared config inherits dig-nat's IPv6-first candidate ordering; `merge_reflexive` keeps IPv6 ahead of IPv4; advertised discovery unchanged. Tests: full ladder enabled (regression guard vs Direct+Relayed), STUN set only when provided, relay-host parsing, reflexive merge ordering (IPv6-first + dedup). Refs #376, #381, #384, #385, #386, #387 Co-Authored-By: Claude <noreply@anthropic.com>
…is the sole locator (#386) `PeerRpcClient` + `find_holders` + `PeerAvailability` predated the DHT and had ZERO live callers (only definitions + a stale doc claiming "#163 dig-dht plugs in behind Self::find_holders" — an integration that never landed; the DHT went in via `NodeContent` instead). Removing the dead seam leaves ONE unambiguous provider path: the dig-dht provider index (`DhtProviderLocator` -> `find_providers`) inside `NodeContent`, used by both the redirect-on-miss and multi-source fetch paths. Rewrites the module doc's stale "clean seam for #163" note accordingly. Refs #376, #253 Co-Authored-By: Claude <noreply@anthropic.com>
Learned peer addresses (PEX, dig.getPeers, introducer, observed pool peers) were dialed-immediately-or-discarded — nothing accumulated a durable, ordered address book to seed later candidate selection. Adds `address_book::AddressBook`: one entry per peer_id, unions dialable addresses IPv6-first (§5.2), records provenance (a first-hand sighting is not downgraded by a later PEX hint) + a freshen timestamp, persists relay-only / not-currently-dialable hints, and reads back a ranked, non-stale candidate list (IPv6-dialable first, then dialable, then relay-only) with a staleness TTL + capacity eviction. Crate-API note (release-first follow-up): dig-gossip owns the canonical AddressManager but exposes NO public production ingest API (only a #[doc(hidden)] test hook), so this book lives node-side for now; when dig-gossip ships a public `offer_addresses` ingest API the book flushes into the crate AddressManager (one source of truth). Documented in the module doc + SPEC §19.7. Tests: IPv6-first ordering + dedup, relay-only persistence, upsert union/freshen, provenance non-downgrade, readback ordering, TTL staleness, capacity eviction. Refs #376 Co-Authored-By: Claude <noreply@anthropic.com>
…l ordering (#387, #384) Two coupled changes to the PEX pool sink (`GossipPexPool::offer_candidates`): #387 — feed PEX-discovered peers into the address book, not dial-and-drop. Every learned candidate (INCLUDING relay-only / not-currently-dialable hints) is offered into the durable address book (#381) with provenance PEX, so nothing is discarded; a hint that can't be reached now persists to seed a later dial. Dials are now sourced from the accumulated book (a superset of this batch), so previously-learned + relay-only-turned-dialable hints are retried; a failed dial keeps the hint in the book. #384 — let dig-peer-selector drive dial choice. Adds a `DialRanker` seam (`SelectorDialRanker` over the shared PeerSelector via its content-agnostic peer_snapshot) that orders which book candidates are dialed first — reliability blended with throughput, banned peers last, cold peers explored at a neutral rank. Reuses the ONE selector instance already ranking download sources (never a second); IPv6-first order preserved among equally-ranked peers. Crate-API note (release-first follow-up): dig-gossip's PeerPoolConfig exposes NO dial-priority hook, so selector ordering applies to the node's PEX candidate dials; when dig-gossip ships a pool dial-priority hook the same ranking drives the pool's own maintenance dial loop. Documented in SPEC §19.6/§19.7. Removes the now-unused `best_socket_addr` helper (superseded by the book's IPv6-first CandidateAddr ordering). Tests: entry→candidate conversion (dialable IPs, relay-only), ranker ordering (good→neutral→bad, None ranker no-op). Refs #376, #381 Co-Authored-By: Claude <noreply@anthropic.com>
Adds SPEC §19 (peer network: full NAT ladder, STUN reflexive discovery, DHT-only locator, durable address book, PEX handling, selector-driven dial ordering, and the release-first crate-API integration status). Applies rustfmt across the P2P-wiring changes and bumps the workspace to v0.19.0 (dig-node-core 0.6.0) — MINOR: new node-side capability (address book + dial ordering), backwards-compatible. Refs #376, #381, #384, #385, #386, #387 Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Wires the dig-node to use its P2P crates (dig-gossip / dig-nat / dig-dht / dig-pex / dig-peer-selector) more fully — one cohesive p2p-wiring branch for the #376 sub-batch. Minor bump to v0.19.0 (dig-node-core 0.6.0).
net::full_nat_confighelper; relay is a genuine last resort. STUN reflexive-address discovery added to the advertised candidate set (IPv6-first).PeerRpcClient::find_holdersseam (0 live callers); dig-dht is the sole content locator.address_book::AddressBook); learned addresses accumulate instead of being dial-and-dropped.Crate-API findings (release-first follow-ups — NOT editable here; single-writer for dig-node only)
The pinned dig-gossip rev (
9177a9b) lacks two intended crate APIs; realized node-side in the interim + flagged for follow-up crate tickets:AddressManager(only a#[doc(hidden)]__seed_address_book_for_testshook). Node keeps its own book; flushes into the crateAddressManageronce dig-gossip ships a publicoffer_addresses(candidates, provenance).PeerPoolConfighas no ranking hook. Selector ordering applies to the node's PEX candidate dials; when dig-gossip ships a pool dial-priority hook the same ranking can drive the pool's own maintenance dial loop.Verification (local)
cargo fmt --all -- --check— cleancargo clippy --workspace --all-targets -- -D warnings— cleancargo test -p dig-node-core --lib— 247 passed, 0 failed (incl. new address_book / net-ladder / STUN / ranker / entry-conversion tests)--all-targets.IPv6-first (§5.2) preserved at every touched dial/candidate/advertise path (full-ladder config inherits dig-nat IPv6-first ordering;
merge_reflexive+ address-book keep IPv6 ahead of IPv4).SPEC §19 documents the peer-network integration contract.
Closes #381, #384, #385, #386, #387
🤖 Generated with Claude Code